/*
 * @brief:
 * @Author: TzzzT
 * @Date: 2022-05-10 13:59:19
 * @LastEditTime: 2023-05-04 02:18:10
 * @LastEditors: TzzzT
 */

#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "esp_gap_ble_api.h"
#include "string.h"

#include "my_ble_server.h"
#include "RCS_system.h"
#include "RCS_ble_master.h"
#include "cJSON.h"
#include "RCS_protocol.h"

static const char *BLE_TAG = "BLE_MAS";

extern QueueHandle_t xGameQueue;
extern rcs_station_system_t rcsSystem;
extern TaskHandle_t bleserverTaskHandle;

static void dev_connected_cb(esp_bd_addr_t cli_bda)
{
    ESP_LOGI(BLE_TAG, " into dev_connected_cb");
}

static void client_disconnected_cb(esp_bd_addr_t cli_bda)
{
    ESP_LOGI(BLE_TAG, " into client_disconnected_cb");
}

static void client_write_cb(esp_bd_addr_t bda, uint8_t *buf, uint8_t buf_len)
{
    ESP_LOGI(BLE_TAG, " into client_write_cb");
}

static void ble_server_cb_register(void)
{
    server_func_t *fun;
    fun = get_server_func_p();
    fun->cli_conn_cb = dev_connected_cb;
    fun->cli_disconn_cb = client_disconnected_cb;
    fun->cli_write_cb = client_write_cb;
}

void remember_ble_setting(void)
{
    ble_server_cb_register();
    // 开启蓝牙底层有限状态机
    ble_server_init();
    esp_err_t err;
    err = get_station_from_nvs();
    if (err != ESP_OK)
    {
        ESP_LOGI(BLE_TAG, "no station");
        rcsSystem.station_type = DEFAULT_STATION;
    }
    else
    {
        ESP_LOGI(BLE_TAG, "station name:%d", rcsSystem.station_type);
    }
}

char adv_name[STATION_CLASS_NUM][12] = {
    "DEF000000",
    "RES000000",
    "SAFETY",
    "TEAM_A",
    "TEAM_B",
    "REBORN",
    "HP_DROP",
    "HP_CURE",
    "INVINCIBLE"};

void rcs_start_advertise(station_type_t sta_type)
{
    store_station_to_nvs();
    char id_ch[7] = {0};
    if (sta_type == DEFAULT_STATION || sta_type == RESOURCE_STATION)
    {
        itoa(rcsSystem.user.id, id_ch, 10);
        uint8_t len = strlen(id_ch);
        if (len <= 6)
        {
            // len=5 9-5 = 4
            // 0 1 2 3 4
            // D E F 0 X X X X X
            strncpy(adv_name[sta_type] + (9 - len), id_ch, len);
        }
    }
    set_adv_device_name((uint8_t *)adv_name[sta_type], strlen(adv_name[sta_type]));
}

bool rcs_is_advertising(void)
{
    return is_server_advertising();
}

void rcs_stop_advertise(void)
{
    ESP_LOGE(BLE_TAG, "rcs_stop_advertise");
    esp_ble_gap_stop_advertising();
}

#define STATION_TYPE_KEY "sta_type"
esp_err_t store_station_to_nvs(void)
{
    nvs_handle devNvsHandle;
    esp_err_t err;
    err = nvs_open("dev_config", NVS_READWRITE, &devNvsHandle);
    if (err != ESP_OK)
    {
        printf("Error (%s) opening NVS devNvsHandle!\n", esp_err_to_name(err));
        return err;
    }
    nvs_set_u8(devNvsHandle, STATION_TYPE_KEY, rcsSystem.station_type);
    err = nvs_commit(devNvsHandle);
    if (err != ESP_OK)
    {
        printf("store_game_start_to_nvs failed, err(%s)\n", esp_err_to_name(err));
        return err;
    }
    nvs_close(devNvsHandle);
    return ESP_OK;
}

esp_err_t get_station_from_nvs(void)
{
    nvs_handle devNvsHandle;
    esp_err_t err;
    err = nvs_open("dev_config", NVS_READWRITE, &devNvsHandle);
    if (err != ESP_OK)
    {
        printf("Error (%s) opening NVS devNvsHandle!\n", esp_err_to_name(err));
        return err;
    }
    uint8_t val = 0;
    err = nvs_get_u8(devNvsHandle, STATION_TYPE_KEY, &val);
    if (err != ESP_OK)
    {
        printf("get_station_from_nvs failed, err(%s)\n", esp_err_to_name(err));
        return err;
    }
    else
    {
        ESP_LOGI(BLE_TAG, "get_station_from_nvs successfully, station_type: %d", val);
    }
    rcsSystem.station_type = val;

    nvs_commit(devNvsHandle);
    nvs_close(devNvsHandle);
    return ESP_OK;
}
